<?php

namespace app\common\library;

use app\common\model\zbtask\Money;
use fast\Random;
use Pingpp\Error\Base;
use Pingpp\Transfer;
use think\Db;
use think\exception\ValidateException;

/**
 *  https://dashboard2.pingxx.com
 *  该类封装该平台的身份认证 支付等功能
 */
class Pingpp
{
    private static $app_key = 'sk_live_Tmf1SCe9Cq5GTmfTC08Sez5O';
    private static $app_id = 'app_vfn5q5Py5m90bnLG';
    private static $allinpayKey = '200586000002341';
    private static $instance;
    private static $privateKey = <<<'key'
-----BEGIN RSA PRIVATE KEY-----
MIICXQIBAAKBgQCvGARS1pfu/ojMktFq8iHNObHJJ9xBT6C6lvhldnVzX0f7YzHG
jCoqRHyL65lhypn0Eh/CLRYZIaKAe0S06ijNoRvNAgPNA0PfKbevD/93HhkFGbHr
n1Owbt/IrSMoIXOYNL8oVocEtGiXieakh0Nou2wVK4Bigb1kyznTVxS9pwIDAQAB
AoGBAJ7UIW/ne5DvUbaI4/CoTeM1F8HKJ7ETA1DfC9o2F5qdbtVqCMf7c3A+CeB+
yfb8aqUNH8PrVCVd7mOv7gZSdsl4wP9x0vWTm1GvkwhKYa0C9xtPEZlmEmBKYrbS
WAFNJjV4AtS67b+XlKop4C+jpisQr2lsAIK1bL75dWA6LbTpAkEA2ZTSKggav1Q9
Mx4wqmY468cmRmvhMd/r+vP3b6+f/4Ho9kFb2IiyoQr3v5PnA2bVa0sYvpVihYYG
y176lxzUGwJBAM4CqXqD3rYvQ6l45FlVrChAWf/aFhcWed7IurxLuyFhz7QRIfVl
+SNWG0x8TlIfE9dVT3OmHEOvPMwzSfzqHWUCQAw4iKlltSLj92AEpRUdErtjfynb
a1Wizx1UUKSMR79RK6WRPDhoTSgwdoPjKcmOIBSbrjMeLt9zDLSljAuqydsCQQCh
6hu0LDL989X1PAwVXq2JkVJrMchM6yBsBk4mMktoqEysFQ8gpb4TlNit28Fe8AgT
JXzlw3fRhsh9Ig6T1pm1AkAqmMDJM2fKhtREBg5SsTWU27bYATNrzBFcUNl52oSX
iRU8m0WSUIFS/2PzLQVPdO1DBSAzcCKdR0dR6m60X318
-----END RSA PRIVATE KEY-----
key;

    private static $publicKey = <<<'key'
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqjO5eEGGjICo5BuXX44z
+3m9Y8cxYHURJpr0APS9B95Ib9ubPK1k7UcxYNEDRmv/+EoK8ke6LMz4ZPuVBVeQ
Lgp/dceOXwZnIZc4SVr5ros7z4FRm5a3JJZQvvXlgQP2AF/jHNzY5xV5LkLshF3v
LOoA5qdTTFXJO1QJ3PDuEhxLK0rWbxQ/tT/UFYmw/WUcYl0M8CioUSWzY7EbyBqw
C803bnwmb2Vxm0YFF3trS9TGAQtTP7P5CLA39FTaWNc7MpKAiKuWO1c9imuliZ9u
veGm9Q3rDUugKhks/82Xl5j9aJqR7USd3W9L/l3dS+3aGzuWBzFUUWIrnSinXoZi
dwIDAQAB
-----END PUBLIC KEY-----
key;
    public function __construct()
    {
        \Pingpp\Pingpp::setApiKey(self::$app_key);
        \Pingpp\Pingpp::setAppId(self::$app_id);
        \Pingpp\Pingpp::setPrivateKey(self::$privateKey);
    }

    //单例访问统一入口
    public static function getInstance()
    {
        if(!(self::$instance instanceof self))
        {
            self::$instance = new self();
        }
        return self::$instance;
    }
    /*实名认证*/
    public function identificationName($data) {
        try {
            $res = \Pingpp\Identification::identify(array(
                'type' => 'id_card',
                'app' => self::$app_id,
                'data' => array(
                    'id_name' => $data['real_name'], // 姓名
                    'id_number' => $data['identity_card'] // 身份证号
                )
            ));
            //res 存在 判断是否认证成功
            if ($res) {
                //成功
                if ($res['result_code'] == 0) {
                    return true;
                } else {  //失败
                    throw new ValidateException($res['message']);
                }
            }
        } catch (\Pingpp\Error\Base $e) {
            throw new ValidateException($e->getMessage());
        } catch (ValidateException $e) {
            throw new ValidateException($e->getMessage());
        }
    }

    /*实名认证*/
    public function identificationBank($data) {
        try {
            $res = \Pingpp\Identification::identify(array(
                'type' => 'bank_card',
                'app' => self::$app_id,
                'data' => array(
                    'id_name' =>  $data['real_name'], // 姓名
                    'id_number' => $data['identity_card'], // 身份证号,
                    'card_number' => $data['bank_card'], // 银行卡号
                    'phone_number' => $data['mobile'] // 银行预留手机号，暂不支持178开头的手机号。
                )
            ));

            //res 存在 判断是否认证成功
            if ($res) {
                //成功
                if ($res['result_code'] == 0) {
                    return true;
                } else {  //失败
                    throw new ValidateException($res['message']);
                }
            }
        } catch (\Pingpp\Error\Base $e) {
            throw new ValidateException($e->getMessage());
        } catch (ValidateException $e) {
            throw new ValidateException($e->getMessage());
        }
    }

    /*
     * 企业单个付款
     * $data['id'] = 打款订单id
     * */
    public function transfer($data) {
        //通联订单号比较铁树
        $order_no = self::$allinpayKey . time() . $data['id'];
        //更新order_no
        Db::name('zbtask_money')->where('id', $data['id'])->setField('order_sn', $order_no);
        // 创建 Transfer
        try {
            //更新order_no
            Transfer::create(
                array(
                    'order_no'    => $order_no,
                    'app'         => array('id' => self::$app_id),
                    'channel'     => 'allinpay',
                    'amount'      => $data['get_money']*100,
                    'currency'    => 'cny',
                    'type'        => 'b2c',
                    'description' => '企业付款',
                    'metadata' => [
                        'order_id' => $data['id'],
                    ],
                    'extra' => [
                        'card_number'=> $data['bank_card'],
                        'user_name'  => $data['real_name'],
                        'open_bank_code' => $data['open_bank_code'],  //开户银行编号
                    ]
                )
            );

        } catch (Base $e) {
            throw new ValidateException($e->getHttpBody());
        } catch (\Exception $e) {
            throw new ValidateException($e->getHttpBody());
        }
    }

    /*
     * 认证是否已经打款  众包费id
     * */
    public function check($id) {
        if (!$id) {
            throw new ValidateException('参数传递错误');
        }
        $info = Db::name('zbtask_money')->where(['id'=> $id])->find();
        if (in_array($info['transfer_type'], [2])) {  //打款成功 不在打款
            return false ; //不通过
        }

        return true;
    }


    /*
     * 企业付款 回调方法
     * */
    public function notify(callable $notify) {
        $raw_data = file_get_contents('php://input');
        // 示例
        // $raw_data = '{"id":"evt_eYa58Wd44Glerl8AgfYfd1sL","created":1434368075,"livemode":true,"type":"charge.succeeded","data":{"object":{"id":"ch_bq9IHKnn6GnLzsS0swOujr4x","object":"charge","created":1434368069,"livemode":true,"paid":true,"refunded":false,"app":"app_vcPcqDeS88ixrPlu","channel":"wx","order_no":"2015d019f7cf6c0d","client_ip":"140.227.22.72","amount":100,"amount_settle":0,"currency":"cny","subject":"An Apple","body":"A Big Red Apple","extra":{},"time_paid":1434368074,"time_expire":1434455469,"time_settle":null,"transaction_no":"1014400031201506150354653857","refunds":{"object":"list","url":"/v1/charges/ch_bq9IHKnn6GnLzsS0swOujr4x/refunds","has_more":false,"data":[]},"amount_refunded":0,"failure_code":null,"failure_msg":null,"metadata":{},"credential":{},"description":null}},"object":"event","pending_webhooks":0,"request":"iar_Xc2SGjrbdmT0eeKWeCsvLhbL"}';

        $headers = \Pingpp\Util\Util::getRequestHeaders();
        // 签名在头部信息的 x-pingplusplus-signature 字段
        $signature = isset($headers['X-Pingplusplus-Signature']) ? $headers['X-Pingplusplus-Signature'] : NULL;
        $pub_key_contents = self::$publicKey;
        $res = openssl_verify($raw_data, base64_decode($signature), $pub_key_contents, 'sha256');

        if ($res === 1) {
            // 验证通过
            $event = json_decode($raw_data, true);
            try {
                if ($event['type'] == 'transfer.succeeded') {
                    $refund = $event['data']['object'];
                    $refund['last_res'] = 1;
                    call_user_func($notify, $refund);
                    http_response_code(200);
                    exit;
                } else {
                    $refund = $event['data']['object'];
                    $refund['last_res'] = 2;
                    call_user_func($notify, $refund);
                    http_response_code(400);
                    exit;
                }

            } catch (\Exception $e) {
                http_response_code(400);
                echo 'verification failed';
                exit;
            }

        } elseif ($res === 0) {
            http_response_code(400);
            echo 'verification failed';
            exit;
        } else {
            http_response_code(400);
            echo 'verification error';
            exit;
        }
    }



}
